package com.j.lemon.learn.elastic;

import java.net.InetAddress;
import java.util.*;

import org.elasticsearch.action.search.SearchRequestBuilder;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.transport.TransportClient;
import org.elasticsearch.common.settings.Settings;
import org.elasticsearch.common.transport.InetSocketTransportAddress;
import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHitField;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.sort.SortOrder;
import org.elasticsearch.transport.client.PreBuiltTransportClient;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

/**
 * @Author lijunjun
 * @Date 2020-07-21 14:28
 * @Description
 */
public class ESQuery {
    private static String host="1"; // 服务器地址
    private static int port=9300; // 端口

    public static final String CLUSTER_NAME = "es-audit-asiainfo"; //集群名称

    private TransportClient client=null;

    private static Settings settings= Settings.builder()
            .put("cluster.name",CLUSTER_NAME)
            .put("client.transport.sniff", true)
            .build();

    //获取客户端
    public TransportClient getClient() throws Exception {
        try {
            client = new PreBuiltTransportClient(settings)
                    .addTransportAddress(new InetSocketTransportAddress(InetAddress.getByName(host),port));
            return client;
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return null;
        }
    }

    //关闭客户端
    public void close() {
        if(client!=null) {
            client.close();
        }
    }

    /**
     * 查询所有
     */
    @Test
    public void searchAll() {
        SearchRequestBuilder srb=client.prepareSearch("film").setTypes("dongzuo");
        SearchResponse sr=srb.setQuery(QueryBuilders.matchAllQuery()).execute().actionGet();//查询所有
        SearchHits hits=sr.getHits();
        for(SearchHit hit:hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
    /**
     * 分页查询
     */
    @Test
    public void searchPaging() {
        SearchRequestBuilder srb=client.prepareSearch("film").setTypes("dongzuo");
        SearchResponse sr=srb.setQuery(QueryBuilders.matchAllQuery()).setFrom(0).setSize(2).execute().actionGet();
        SearchHits hits=sr.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
    /**
     * 排序查询
     */
    @Test
    public void searchOrderBy() {
        SearchRequestBuilder srb=client.prepareSearch("film").setTypes("dongzuo");
        SearchResponse sr=srb.setQuery(QueryBuilders.matchAllQuery())
                .addSort("publishDate", SortOrder.DESC).execute().actionGet();
        SearchHits hits=sr.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
    /**
     * 数据列过滤查询
     */
    @Test
    public void searchInclude() {
        SearchRequestBuilder srb=client.prepareSearch("film").setTypes("dongzuo");
        SearchResponse sr=srb.setQuery(QueryBuilders.matchAllQuery())
                .setFetchSource(new String[] {"title","price"},null)
                .execute()
                .actionGet();
        SearchHits hits=sr.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
    /***
     * 简单条件查询
     */
    @Test
    public void searchByCondition() {
        SearchRequestBuilder srb=client.prepareSearch("film").setTypes("dongzuo");
        SearchResponse sr=srb.setQuery(QueryBuilders.matchQuery("title","铁"))
                .setFetchSource(new String[] {"title","price"},null)
                .execute()
                .actionGet();
        SearchHits hits=sr.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }
    /**
     * 条件查询高亮实现
     */
    @Test
    public void searchHighlight() {
        SearchRequestBuilder srb=client.prepareSearch("film").setTypes("dongzuo");
        HighlightBuilder highlightBuilder=new HighlightBuilder();
        highlightBuilder.preTags("<h2>");
        highlightBuilder.postTags("</h2>");
        highlightBuilder.field("title");
        SearchResponse sr=srb.setQuery(QueryBuilders.matchQuery("title","战"))
                .highlighter(highlightBuilder)
                .setFetchSource(new String[] {"title","price"},null)
                .execute()
                .actionGet();
        SearchHits hits=sr.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
            System.out.println(hit.getHighlightFields());
        }
    }
    /**
     * 多条件查询  must
     */
    @Test
    public void searchMutil() {
        SearchRequestBuilder srb =client.prepareSearch("film").setTypes("dongzuo");
        QueryBuilder queryBuilder=QueryBuilders.matchPhraseQuery("title", "战");
        QueryBuilder queryBuilder2=QueryBuilders.matchPhraseQuery("content", "星球");
        SearchResponse sr=srb.setQuery(QueryBuilders.boolQuery()
                .must(queryBuilder)
                .must(queryBuilder2))
                .execute()
                .actionGet();
        SearchHits hits=sr.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     * 多条件查询  mustNot
     */
    @Test
    public void searchMutil2() {
        SearchRequestBuilder srb =client.prepareSearch("film").setTypes("dongzuo");
        QueryBuilder queryBuilder=QueryBuilders.matchPhraseQuery("title", "战");
        QueryBuilder queryBuilder2=QueryBuilders.matchPhraseQuery("content", "武士");
        SearchResponse sr=srb.setQuery(QueryBuilders.boolQuery()
                .must(queryBuilder)
                .mustNot(queryBuilder2))
                .execute()
                .actionGet();
        SearchHits hits=sr.getHits();
        for (SearchHit hit : hits) {
            System.out.println(hit.getSourceAsString());
        }
    }

    /**
     * 多条件查询  should提高得分
     * @throws Exception
     */
    @Test
    public void searchMutil3()throws Exception{
        SearchRequestBuilder srb=client.prepareSearch("film").setTypes("dongzuo");
        QueryBuilder queryBuilder=QueryBuilders.matchPhraseQuery("title", "战");
        QueryBuilder queryBuilder2=QueryBuilders.matchPhraseQuery("content", "星球");
        QueryBuilder queryBuilder3=QueryBuilders.rangeQuery("publishDate").gt("2018-01-01");
        SearchResponse sr=srb.setQuery(QueryBuilders.boolQuery()
                .must(queryBuilder)
                .should(queryBuilder2)
                .should(queryBuilder3))
                .execute()
                .actionGet();
        SearchHits hits=sr.getHits();
        for(SearchHit hit:hits){
            System.out.println(hit.getScore()+":"+hit.getSourceAsString());
        }
    }
    public static void main(String[] args) throws Exception {
//        String [] s =  new String[]{"iap_app_log_gold_","iap_app_log_round_","iap_app_log_","iap_dev_cmd_",
//                                    "iap_dev_round_","iap_device_session_cmd_","iap_device_session_cmd_gold_",
//                                    "iap_device_session_end_gold","iap_device_session_end","iap_device_session_gold",
//                                    "iap_device_session","iap_ori_app_log_","iap_ori_dev_session_cmd_","iap_ori_dev_session_end_",
//                                    "iap_ori_device_session_"};

        Map<String, Integer> countResult = new HashMap<>();
        Map<String, Set<String>> resultMap = new HashMap<>();
        ESQuery esQuery = new ESQuery();
        TransportClient client = esQuery.getClient();
//        SearchRequestBuilder srb = client.prepareSearch("mysql_error-log-v1").setTypes("mysql_error-log-2020-07");
        SearchRequestBuilder srb = client.prepareSearch("mysql_error-log-v1").setTypes("mysql_error-log-2020-07");
        QueryBuilder queryBuilder1=QueryBuilders.rangeQuery("LOGTIME").lte("2020-07-20 00:00:00");
        QueryBuilder queryBuilder2=QueryBuilders.rangeQuery("LOGTIME").lte("2020-07-21 00:00:00");
        SearchResponse sr=srb.setQuery(QueryBuilders.boolQuery()
                .filter(queryBuilder1).filter(queryBuilder2))
                .execute()
                .actionGet();
        SearchHits hits=sr.getHits();
        System.out.println(hits.getTotalHits());
        for (SearchHit hit : hits) {
            SearchHitField prefix = hit.field("SINK_NAME");
            String prefixValue = String.valueOf(prefix.getValue());

            //统计种类
            Set<String> set = resultMap.get(prefixValue);
            if(set == null){
                set = new HashSet<>();
            }
            String error = String.valueOf(hit.field("ERROR").value());
            if(error.contains("Duplicate entry")){
                set.add("Duplicate entry");
            }else{
                set.add(error.substring(0,error.indexOf("at")));
            }
            resultMap.put(prefixValue,set);

            //统计数量
            Integer integer = countResult.get(prefixValue);
            if(integer==null){
                integer = 0;
            }
            integer++;
            countResult.put(prefixValue,integer);
        }
    }
}
